package hied.generator;

import hied.Example;
import hied.ExampleList;
import hied.Parameters;
import hied.TextContainer;

import java.io.File;
import java.util.ArrayList;
import java.util.Random;

import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;

public class TrainSetGeneratorApplication {
	private static ArrayList<TextContainer> titles = new ArrayList<TextContainer>();
	private static ArrayList<TextContainer> firstNames = new ArrayList<TextContainer>();
	private static ArrayList<TextContainer> lastNames = new ArrayList<TextContainer>();
	private static Random rand = new Random();
	private static final String TARGET = "target.xml";
	private static final char[] CHARS = new char[] { 'a', 'ą', 'b', 'c', 'ć', 'd', 'e', 'ę', 'f',
			'g', 'h', 'i', 'j', 'k', 'l', 'ł', 'm', 'n', 'ń', 'o', 'ó', 'p', 'q', 'r', 's', 'ś',
			't', 'u', 'v', 'w', 'x', 'y', 'z', 'ź', 'ż' };
	static {
		TrainSetGeneratorApplication.fillLists();
	}

	public static void main(String[] args) throws Exception {
		ExampleList list = TrainSetGeneratorApplication.generateExamples(Parameters
				.getTrainSetSize());
		TrainSetGeneratorApplication.serializeToFile(list, TARGET);
	}

	private static void serializeToFile(ExampleList list, String fileName) throws Exception {
		Serializer serializer = new Persister();
		File target = new File(fileName);
		serializer.write(list, target);
	}

	public static ExampleList generateExamples(int n) {
		ExampleList list = new ExampleList();
		for (int i = 0; i < n; i++) {
			Example newExample = TrainSetGeneratorApplication.generateExample();
			// System.out.println(newExample);
			list.addExample(newExample);
		}
		return list;
	}

	private static Example generateExample() {
		TextContainer titleContainer = TrainSetGeneratorApplication
				.getRandom(TrainSetGeneratorApplication.titles);
		TextContainer fnameContainer = TrainSetGeneratorApplication
				.getRandom(TrainSetGeneratorApplication.firstNames);
		TextContainer lnameContainer = TrainSetGeneratorApplication
				.getRandom(TrainSetGeneratorApplication.lastNames);
		String title = possiblyDamage(titleContainer.getIncorrect());
		String fname = possiblyDamage(fnameContainer.getIncorrect());
		String lname = possiblyDamage(lnameContainer.getIncorrect());
		String incorrect = lname + " " + fname + ", " + title;
		String correct = titleContainer.getCorrect() + " " + fnameContainer.getCorrect() + " "
				+ lnameContainer.getCorrect();
		return new Example(incorrect, correct);
	}

	private static String possiblyDamage(String incorrect) {
		if (Parameters.getDamageProbability() <= rand.nextInt(100)) {
			return damage(incorrect);
		}
		return incorrect;
	}

	private static String damage(String incorrect) {
		String result = incorrect;
		if (rand.nextBoolean()) {
			result = addChar(result);
		}
		if (rand.nextBoolean()) {
			result = removeChar(result);
		}
		if (rand.nextBoolean()) {
			result = changeChar(result);
		}
		return result;
	}

	private static String changeChar(String incorrect) {
		int index = rand.nextInt(incorrect.length());
		String pre = incorrect.substring(0, index);
		char character = CHARS[rand.nextInt(CHARS.length)];
		String post = incorrect.substring(index + 1);
		return pre + character + post;
	}

	private static String removeChar(String incorrect) {
		int index = rand.nextInt(incorrect.length());
		String pre = incorrect.substring(0, index);
		String post = incorrect.substring(index + 1);
		return pre + post;
	}

	private static String addChar(String incorrect) {
		int index = rand.nextInt(incorrect.length());
		String pre = incorrect.substring(0, index);
		char character = CHARS[rand.nextInt(CHARS.length)];
		String post = incorrect.substring(index);
		return pre + character + post;
	}

	private static TextContainer getRandom(ArrayList<TextContainer> titles) {
		int size = titles.size();
		return titles.get(rand.nextInt(size));
	}

	private static void fillLists() {
		TrainSetGeneratorApplication.titles.add(new TextContainer("profesor", "prof."));
		TrainSetGeneratorApplication.titles.add(new TextContainer("doktor", "dr"));
		TrainSetGeneratorApplication.titles
				.add(new TextContainer("doktor habilitowany", "dr hab."));
		TrainSetGeneratorApplication.titles.add(new TextContainer(
				"profesor doktor habilitowany inżynier", "prof. dr hab. inż."));
		TrainSetGeneratorApplication.titles.add(new TextContainer("doktor inżynier", "dr inż."));
		TrainSetGeneratorApplication.titles.add(new TextContainer("inżynier", "inż."));
		TrainSetGeneratorApplication.titles.add(new TextContainer("magister", "mgr"));
		TrainSetGeneratorApplication.titles.add(new TextContainer("magister inżynier", "mgr inż."));
		TrainSetGeneratorApplication.titles.add(new TextContainer("licencjat", "lic."));
		TrainSetGeneratorApplication.firstNames.add(new TextContainer("Paweł", "Paweł"));
		TrainSetGeneratorApplication.firstNames.add(new TextContainer("Józef", "Józef"));
		TrainSetGeneratorApplication.firstNames.add(new TextContainer("Kazimierz", "Kazimierz"));
		TrainSetGeneratorApplication.firstNames.add(new TextContainer("Antoni", "Antoni"));
		TrainSetGeneratorApplication.firstNames.add(new TextContainer("Waldemar", "Waldemar"));
		TrainSetGeneratorApplication.firstNames.add(new TextContainer("Waldek", "Waldemar"));
		TrainSetGeneratorApplication.firstNames.add(new TextContainer("Kaziu", "Kazimierz"));
		TrainSetGeneratorApplication.firstNames.add(new TextContainer("Julka", "Julia"));
		TrainSetGeneratorApplication.firstNames.add(new TextContainer("Andrzej", "Andrzej"));
		TrainSetGeneratorApplication.firstNames.add(new TextContainer("Marek", "Marek"));
		TrainSetGeneratorApplication.firstNames.add(new TextContainer("Łukasz", "Łukasz"));
		TrainSetGeneratorApplication.lastNames.add(new TextContainer("Nowak", "Nowak"));
		TrainSetGeneratorApplication.lastNames.add(new TextContainer("Kowalski", "Kowalski"));
		TrainSetGeneratorApplication.lastNames.add(new TextContainer("Mańkowki", "Mańkowski"));
		TrainSetGeneratorApplication.lastNames.add(new TextContainer("Gołota", "Gołota"));
		TrainSetGeneratorApplication.lastNames.add(new TextContainer("Golota", "Gołota"));
		TrainSetGeneratorApplication.lastNames.add(new TextContainer("Klops", "Klops"));
		TrainSetGeneratorApplication.lastNames.add(new TextContainer("Giertych", "Giertych"));
		TrainSetGeneratorApplication.lastNames.add(new TextContainer("Lepper", "Lepper"));
		TrainSetGeneratorApplication.lastNames.add(new TextContainer("Jones", "Jones"));
		TrainSetGeneratorApplication.lastNames.add(new TextContainer("Kaczynski", "Kaczyński"));
		TrainSetGeneratorApplication.lastNames.add(new TextContainer("Kaczyński", "Kaczyński"));
	}

}
